package com.hsurosy.hsuchain.nft.notice.facade;

import cn.hutool.core.util.RandomUtil;
import com.hsurosy.hsuchain.nft.api.notice.response.NoticeResponse;
import com.hsurosy.hsuchain.nft.api.notice.service.NoticeFacadeService;
import com.hsurosy.hsuchain.nft.base.exception.BizException;
import com.hsurosy.hsuchain.nft.limiter.SlidingWindowRateLimiter;
import com.hsurosy.hsuchain.nft.notice.domain.constant.NoticeState;
import com.hsurosy.hsuchain.nft.notice.domain.entity.Notice;
import com.hsurosy.hsuchain.nft.notice.domain.service.NoticeService;
import com.hsurosy.hsuchain.nft.rpc.facade.Facade;
import com.hsurosy.hsuchain.nft.sms.SmsService;
import com.hsurosy.hsuchain.nft.sms.response.SmsSendResponse;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;


import java.util.Date;
import java.util.concurrent.TimeUnit;

import static com.hsurosy.hsuchain.nft.api.notice.constant.NoticeConstant.CAPTCHA_KEY_PREFIX;
import static com.hsurosy.hsuchain.nft.base.exception.BizErrorCode.SEND_NOTICE_DUPLICATED;

/**
 * 短信通知外观服务实现类
 *
 * @Author Hsu琛君珩
 * @Date 2024-10-05 16:56
 * @Description
 * @Version: v1.0.0
 */
@DubboService(version = "1.0.0")
public class NoticeFacadeServiceImpl implements NoticeFacadeService {

    @Autowired
    private SlidingWindowRateLimiter slidingWindowRateLimiter;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private SmsService smsService;

    /**
     * 生成并发送短信验证码
     *
     * @param telephone 手机号码
     * @return NoticeResponse 短信发送结果的响应对象
     */
    @Facade
    @Override
    public NoticeResponse generateAndSendSmsCaptcha(String telephone) {
        // 限流操作，防止短时间内多次发送
        boolean rateLimitPassed = slidingWindowRateLimiter.tryAcquire(telephone, 1, 60);
        if (!rateLimitPassed) {
            throw new BizException(SEND_NOTICE_DUPLICATED);
        }

        // 生成4位数字验证码
        String captcha = RandomUtil.randomNumbers(4);

        // 将验证码存入Redis，设置有效期5分钟
        String redisKey = CAPTCHA_KEY_PREFIX + telephone;
        redisTemplate.opsForValue().set(redisKey, captcha, 5, TimeUnit.MINUTES);

        // 保存验证码通知信息到数据库
        Notice notice = noticeService.saveCaptcha(telephone, captcha);

        // 异步发送短信验证码
        Thread.ofVirtual().start(() -> {
            SmsSendResponse result = smsService.sendMsg(notice.getTargetAddress(), notice.getNoticeContent());
            if (result.getSuccess()) {
                // 短信发送成功，更新通知状态为SUCCESS
                notice.setState(NoticeState.SUCCESS);
                notice.setSendSuccessTime(new Date());
                noticeService.updateById(notice);
            } else {
                // 短信发送失败，更新通知状态为FAILED并保存发送结果
                notice.setState(NoticeState.FAILED);
                notice.addExtendInfo("executeResult", JSON.toJSONString(result));
                noticeService.updateById(notice);
            }
        });

        // 返回成功响应
        return new NoticeResponse.Builder().setSuccess(true).build();
    }
}
